import java.util.Random;
import java.util.HashSet;
import java.util.Set;

/**
 * 加减法口算练习系统-v0.3
 * 功能升级：
 * 1. 生成无重复算式（加法/减法分别去重，如 2+3 和 3+2 视为不同算式）
 * 2. 支持自定义加减法比例（手动配置加法、减法题数）
 * 3. 保留v0.2全部功能：1~199参与运算、加法和≤100、减法差≥0、含答案、每行3道排版
 */
public class CalculationSystemV03 {
    // 核心配置：总题数、加法题数、减法题数（加法数 + 减法数 = 总题数）
    private static final int TOTAL_EXERCISES = 50;
    private static final int ADDITION_COUNT = 30; // 30道加法
    private static final int SUBTRACTION_COUNT = 20; // 20道减法
    // 配置：每行显示的算式数量
    private static final int EXERCISES_PER_LINE = 3;
    // 存储已生成的算式标识（唯一键），用于去重（如 "12+34"、"56-23"）
    private static final Set<String> generatedFormulas = new HashSet<>();

    public static void main(String[] args) {
        // 校验配置：加法+减法是否等于总题数
        if (ADDITION_COUNT + SUBTRACTION_COUNT != TOTAL_EXERCISES) {
            System.err.println("配置错误：加法题数 + 减法题数 ≠ 总题数！");
            return;
        }

        // 打印系统标题
        System.out.println("==================== 加减法口算练习系统-v0.3 ====================");
        System.out.printf("温馨提示：以下为%d道口算题（加法%d道，减法%d道，无重复，含答案）%n",
                TOTAL_EXERCISES, ADDITION_COUNT, SUBTRACTION_COUNT);
        System.out.println("规则：加法和≤100，减法差≥0，支持1~199参与运算\n");

        // 生成习题（先加后减，按比例生成）
        Exercise[] exercises = new Exercise[TOTAL_EXERCISES];
        generateSpecificTypeExercises(exercises, 0, ADDITION_COUNT, true); // 前30道加法
        generateSpecificTypeExercises(exercises, ADDITION_COUNT, SUBTRACTION_COUNT, false); // 后20道减法

        // 按“每行3道”格式输出
        printExercisesInLines(exercises);

        System.out.println("\n================================================================");
    }

    /**
     * 自定义Exercise类：封装算式字符串和对应答案（沿用v0.2，保持兼容性）
     */
    static class Exercise {
        String formula; // 算式（如 "123 - 56 = ?"）
        int answer;     // 答案（如 67）

        public Exercise(String formula, int answer) {
            this.formula = formula;
            this.answer = answer;
        }
    }

    /**
     * 生成指定类型、指定数量的无重复习题，并填入数组指定位置
     * @param exercises 存储习题的数组
     * @param startIndex 数组起始位置（填入起点）
     * @param count 要生成的该类型题数
     * @param isAddition true=加法，false=减法
     */
    public static void generateSpecificTypeExercises(Exercise[] exercises, int startIndex, int count, boolean isAddition) {
        Random random = new Random();
        int generatedCount = 0; // 已生成的该类型题数

        while (generatedCount < count) {
            int num1, num2, answer;
            String formulaStr; // 最终显示的算式（如 " 45 +  36 = ?"）
            String uniqueKey;  // 算式唯一标识（如 "45+36"，用于去重）

            if (isAddition) {
                // 加法逻辑：num1(1~99) + num2(1~(100-num1))，和≤100
                num1 = random.nextInt(99) + 1;
                num2 = random.nextInt(100 - num1) + 1;
                answer = num1 + num2;
                formulaStr = String.format("%3d + %3d = ?", num1, num2);
                uniqueKey = num1 + "+" + num2; // 加法唯一键（顺序相关，2+3≠3+2）
            } else {
                // 减法逻辑：num1(1~199) - num2(1~num1)，差≥0
                num1 = random.nextInt(199) + 1;
                num2 = random.nextInt(num1) + 1;
                answer = num1 - num2;
                formulaStr = String.format("%3d - %3d = ?", num1, num2);
                uniqueKey = num1 + "-" + num2; // 减法唯一键（顺序固定，被减数-减数）
            }

            // 去重校验：如果该算式未生成过，则存入数组和Set
            if (!generatedFormulas.contains(uniqueKey)) {
                generatedFormulas.add(uniqueKey); // 记录已生成的算式
                exercises[startIndex + generatedCount] = new Exercise(formulaStr, answer);
                generatedCount++; // 已生成数量+1
            }
        }
    }

    /**
     * 按每行指定数量打印习题（沿用v0.2的排版逻辑，保持整齐）
     * @param exercises 习题数组
     */
    public static void printExercisesInLines(Exercise[] exercises) {
        for (int i = 0; i < exercises.length; i++) {
            Exercise ex = exercises[i];
            // 格式化：序号（2位）+ 算式（固定长度）+ 答案（标注）
            String lineItem = String.format("%2d. %-20s （答案：%3d）     ",
                    i + 1, ex.formula, ex.answer);

            System.out.print(lineItem);

            // 每EXERCISES_PER_LINE道题换行，最后一道题无需额外换行
            if ((i + 1) % EXERCISES_PER_LINE == 0) {
                System.out.println();
            }
        }
        // 若总题数不是每行数量的整数倍，补一行换行
        if (exercises.length % EXERCISES_PER_LINE != 0) {
            System.out.println();
        }
    }
}